// Redis客户端中文封装
const Redis = require('redis');

/**
 * 创建Redis客户端
 * @param {Object} 配置 - Redis连接配置
 * @returns {RedisClient} Redis客户端实例
 */
function 创建客户端(配置) {
  if (!配置) {
    配置 = {};
  }
  return Redis.createClient(配置);
}

/**
 * 连接到Redis服务器
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {Function} 回调函数 - 连接完成的回调函数
 */
function 连接(客户端, 回调函数) {
  客户端.connect().then(() => {
    if (回调函数) {
      回调函数(null);
    }
  }).catch((错误) => {
    if (回调函数) {
      回调函数(错误);
    } else {
      throw 错误;
    }
  });
}

/**
 * 断开与Redis服务器的连接
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @returns {Promise} 断开连接的Promise
 */
function 断开连接(客户端) {
  return 客户端.disconnect();
}

/**
 * 检查Redis连接状态
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @returns {boolean} 连接状态
 */
function 检查连接状态(客户端) {
  return 客户端.isReady;
}

/**
 * 设置键值对
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @param {any} 值 - 值
 * @param {Object} 选项 - 可选参数
 * @returns {Promise<string>} 操作结果
 */
async function 设置(客户端, 键, 值, 选项) {
  if (!选项) {
    选项 = {};
  }
  return 客户端.set(键, 值, 选项);
}

/**
 * 获取键对应的值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<string>} 值
 */
async function 获取(客户端, 键) {
  return 客户端.get(键);
}

/**
 * 删除键
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string|Array} 键 - 一个或多个键名
 * @returns {Promise<number>} 删除的键数量
 */
async function 删除(客户端, 键) {
  if (Array.isArray(键)) {
    return 客户端.del(...键);
  }
  return 客户端.del(键);
}

/**
 * 检查键是否存在
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<boolean>} 是否存在
 */
async function 是否存在(客户端, 键) {
  const 结果 = await 客户端.exists(键);
  return 结果 === 1;
}

/**
 * 设置键的过期时间
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @param {number} 秒数 - 过期时间（秒）
 * @returns {Promise<number>} 操作结果
 */
async function 设置过期时间(客户端, 键, 秒数) {
  return 客户端.expire(键, 秒数);
}

/**
 * 获取键的剩余过期时间
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<number>} 剩余过期时间（秒）
 */
async function 获取剩余过期时间(客户端, 键) {
  return 客户端.ttl(键);
}

/**
 * 移除键的过期时间
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<number>} 操作结果
 */
async function 移除过期时间(客户端, 键) {
  return 客户端.persist(键);
}

/**
 * 递增数字
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<number>} 递增后的值
 */
async function 递增(客户端, 键) {
  return 客户端.incr(键);
}

/**
 * 递减数字
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @returns {Promise<number>} 递减后的值
 */
async function 递减(客户端, 键) {
  return 客户端.decr(键);
}

/**
 * 增加指定值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @param {number} 增量 - 增加的值
 * @returns {Promise<number>} 增加后的值
 */
async function 增加(客户端, 键, 增量) {
  return 客户端.incrBy(键, 增量);
}

/**
 * 减少指定值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 键名
 * @param {number} 减量 - 减少的值
 * @returns {Promise<number>} 减少后的值
 */
async function 减少(客户端, 键, 减量) {
  return 客户端.decrBy(键, 减量);
}

/**
 * 哈希操作：设置字段值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @param {string} 字段 - 字段名
 * @param {any} 值 - 值
 * @returns {Promise<number>} 操作结果
 */
async function 设置哈希字段(客户端, 键, 字段, 值) {
  return 客户端.hset(键, 字段, 值);
}

/**
 * 哈希操作：批量设置字段值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @param {Object} 数据 - 字段值对象
 * @returns {Promise<number>} 设置的字段数量
 */
async function 设置哈希多个字段(客户端, 键, 数据) {
  return 客户端.hset(键, 数据);
}

/**
 * 哈希操作：获取字段值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @param {string} 字段 - 字段名
 * @returns {Promise<string>} 字段值
 */
async function 获取哈希字段(客户端, 键, 字段) {
  return 客户端.hget(键, 字段);
}

/**
 * 哈希操作：获取所有字段和值
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @returns {Promise<Object>} 所有字段和值
 */
async function 获取哈希所有字段(客户端, 键) {
  return 客户端.hgetall(键);
}

/**
 * 哈希操作：删除字段
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @param {string|Array} 字段 - 一个或多个字段名
 * @returns {Promise<number>} 删除的字段数量
 */
async function 删除哈希字段(客户端, 键, 字段) {
  if (Array.isArray(字段)) {
    return 客户端.hdel(键, ...字段);
  }
  return 客户端.hdel(键, 字段);
}

/**
 * 哈希操作：检查字段是否存在
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 哈希表键名
 * @param {string} 字段 - 字段名
 * @returns {Promise<boolean>} 是否存在
 */
async function 哈希字段是否存在(客户端, 键, 字段) {
  const 结果 = await 客户端.hexists(键, 字段);
  return 结果 === 1;
}

/**
 * 列表操作：添加元素到列表头部
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @param {any} 元素 - 要添加的元素
 * @returns {Promise<number>} 列表长度
 */
async function 列表头部添加(客户端, 键, 元素) {
  return 客户端.lpush(键, 元素);
}

/**
 * 列表操作：添加元素到列表尾部
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @param {any} 元素 - 要添加的元素
 * @returns {Promise<number>} 列表长度
 */
async function 列表尾部添加(客户端, 键, 元素) {
  return 客户端.rpush(键, 元素);
}

/**
 * 列表操作：获取列表长度
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @returns {Promise<number>} 列表长度
 */
async function 获取列表长度(客户端, 键) {
  return 客户端.llen(键);
}

/**
 * 列表操作：获取列表元素
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @param {number} 开始索引 - 开始位置
 * @param {number} 结束索引 - 结束位置
 * @returns {Promise<Array>} 元素数组
 */
async function 获取列表元素(客户端, 键, 开始索引, 结束索引) {
  return 客户端.lrange(键, 开始索引, 结束索引);
}

/**
 * 列表操作：从列表头部移除元素
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @returns {Promise<string>} 移除的元素
 */
async function 列表头部移除(客户端, 键) {
  return 客户端.lpop(键);
}

/**
 * 列表操作：从列表尾部移除元素
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 列表键名
 * @returns {Promise<string>} 移除的元素
 */
async function 列表尾部移除(客户端, 键) {
  return 客户端.rpop(键);
}

/**
 * 集合操作：添加成员
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 集合键名
 * @param {any} 成员 - 要添加的成员
 * @returns {Promise<number>} 添加的成员数量
 */
async function 集合添加成员(客户端, 键, 成员) {
  if (Array.isArray(成员)) {
    return 客户端.sadd(键, ...成员);
  }
  return 客户端.sadd(键, 成员);
}

/**
 * 集合操作：移除成员
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 集合键名
 * @param {any} 成员 - 要移除的成员
 * @returns {Promise<number>} 移除的成员数量
 */
async function 集合移除成员(客户端, 键, 成员) {
  if (Array.isArray(成员)) {
    return 客户端.srem(键, ...成员);
  }
  return 客户端.srem(键, 成员);
}

/**
 * 集合操作：检查成员是否存在
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 集合键名
 * @param {any} 成员 - 要检查的成员
 * @returns {Promise<boolean>} 是否存在
 */
async function 集合成员是否存在(客户端, 键, 成员) {
  const 结果 = await 客户端.sismember(键, 成员);
  return 结果 === 1;
}

/**
 * 集合操作：获取所有成员
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 集合键名
 * @returns {Promise<Array>} 成员数组
 */
async function 获取集合所有成员(客户端, 键) {
  return 客户端.smembers(键);
}

/**
 * 集合操作：获取集合大小
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 集合键名
 * @returns {Promise<number>} 集合大小
 */
async function 获取集合大小(客户端, 键) {
  return 客户端.scard(键);
}

/**
 * 有序集合操作：添加成员和分数
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 有序集合键名
 * @param {number} 分数 - 成员分数
 * @param {any} 成员 - 成员名
 * @returns {Promise<number>} 添加的成员数量
 */
async function 有序集合添加成员(客户端, 键, 分数, 成员) {
  return 客户端.zadd(键, { score: 分数, value: 成员 });
}

/**
 * 有序集合操作：批量添加成员和分数
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 有序集合键名
 * @param {Array} 成员列表 - [{score: 分数, value: 成员}, ...]
 * @returns {Promise<number>} 添加的成员数量
 */
async function 有序集合批量添加(客户端, 键, 成员列表) {
  const 操作数组 = [];
  成员列表.forEach(item => {
    操作数组.push(item.score, item.value);
  });
  return 客户端.zadd(键, ...操作数组);
}

/**
 * 有序集合操作：获取成员分数
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 有序集合键名
 * @param {any} 成员 - 成员名
 * @returns {Promise<string>} 分数
 */
async function 获取有序集合成员分数(客户端, 键, 成员) {
  return 客户端.zscore(键, 成员);
}

/**
 * 有序集合操作：获取有序集合范围成员
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 键 - 有序集合键名
 * @param {number} 开始索引 - 开始位置
 * @param {number} 结束索引 - 结束位置
 * @returns {Promise<Array>} 成员数组
 */
async function 获取有序集合范围成员(客户端, 键, 开始索引, 结束索引) {
  return 客户端.zrange(键, 开始索引, 结束索引);
}

/**
 * 发布消息
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 频道 - 频道名称
 * @param {string} 消息 - 消息内容
 * @returns {Promise<number>} 接收消息的客户端数量
 */
async function 发布消息(客户端, 频道, 消息) {
  return 客户端.publish(频道, 消息);
}

/**
 * 订阅频道
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 频道 - 频道名称
 * @param {Function} 回调函数 - 接收消息的回调函数
 */
function 订阅频道(客户端, 频道, 回调函数) {
  const 订阅客户端 = Redis.createClient(客户端.options);
  订阅客户端.connect().then(() => {
    订阅客户端.subscribe(频道, (消息) => {
      回调函数(消息);
    });
  });
  return 订阅客户端;
}

/**
 * 执行Redis命令
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 命令 - 命令名称
 * @param  {...any} 参数 - 命令参数
 * @returns {Promise<any>} 命令执行结果
 */
async function 执行命令(客户端, 命令, ...参数) {
  return 客户端.sendCommand([命令, ...参数]);
}

/**
 * 生成Redis客户端实例ID
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @returns {Promise<string>} 客户端ID
 */
async function 获取客户端ID(客户端) {
  return 客户端.clientId();
}

/**
 * 获取Redis服务器信息
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 部分 - 可选的信息部分
 * @returns {Promise<Object>} 服务器信息
 */
async function 获取服务器信息(客户端, 部分) {
  return 客户端.info(部分);
}

/**
 * 清空当前数据库
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @returns {Promise<string>} 操作结果
 */
async function 清空数据库(客户端) {
  return 客户端.flushDb();
}

/**
 * 清空所有数据库
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @returns {Promise<string>} 操作结果
 */
async function 清空所有数据库(客户端) {
  return 客户端.flushAll();
}

/**
 * 监控Redis命令执行
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {Function} 回调函数 - 接收监控事件的回调函数
 */
function 监控(客户端, 回调函数) {
  客户端.monitor().then(监控器 => {
    监控器.on('monitor', (时间戳, 客户端信息, 命令, 参数) => {
      回调函数({ 时间戳, 客户端信息, 命令, 参数 });
    });
  });
}

/**
 * 获取所有键
 * @param {RedisClient} 客户端 - Redis客户端实例
 * @param {string} 模式 - 可选的模式匹配
 * @returns {Promise<Array>} 键数组
 */
async function 获取所有键(客户端, 模式 = '*') {
  return 客户端.keys(模式);
}

module.exports = {
  // 客户端管理
  创建客户端,
  连接,
  断开连接,
  检查连接状态,
  获取客户端ID,
  
  // 基础操作
  设置,
  获取,
  删除,
  是否存在,
  设置过期时间,
  获取剩余过期时间,
  移除过期时间,
  
  // 数值操作
  递增,
  递减,
  增加,
  减少,
  
  // 哈希操作
  设置哈希字段,
  设置哈希多个字段,
  获取哈希字段,
  获取哈希所有字段,
  删除哈希字段,
  哈希字段是否存在,
  
  // 列表操作
  列表头部添加,
  列表尾部添加,
  获取列表长度,
  获取列表元素,
  列表头部移除,
  列表尾部移除,
  
  // 集合操作
  集合添加成员,
  集合移除成员,
  集合成员是否存在,
  获取集合所有成员,
  获取集合大小,
  
  // 有序集合操作
  有序集合添加成员,
  有序集合批量添加,
  获取有序集合成员分数,
  获取有序集合范围成员,
  
  // 发布订阅
  发布消息,
  订阅频道,
  
  // 服务器操作
  执行命令,
  获取服务器信息,
  清空数据库,
  清空所有数据库,
  监控,
  获取所有键,
  
  // 工具函数
  获取原始Redis: () => Redis,
  
  // 版本信息
  版本: '1.0.0'
};